package com.paxcodi.rmi.chat;

import java.io.BufferedInputStream;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.MalformedURLException;
import java.rmi.Naming;
import java.rmi.NotBoundException;
import java.rmi.RemoteException;


public class ChatClient implements Runnable {

    private String userName;
    private BufferedReader readFromCommandline;
    private static final String quitKeyword = "QUIT!";
    private Chat chat;

    /**
     * Initializes client with username to use during chat.
     *
     */
    ChatClient(String userName, Chat chatServer) {
	this.userName = userName;
	this.chat = chatServer;

	//join chat, i.e. register as participant at ChatServer
	try {
	    chat.register(userName);
	} catch (RemoteException e) {
	    System.err.println("Registration at ChatServer failed: " + e);
	}

	//construct input-mechanism
	InputStream routeFromCommandline = 
	    new BufferedInputStream(System.in);//in bytes
	InputStreamReader unbufferedReadFromCommandline = 
	    new InputStreamReader(routeFromCommandline); //in characters, unbuff.
	readFromCommandline = 
	    new BufferedReader(unbufferedReadFromCommandline); //in chars, buff.

	//readUserInputLoop();
    }

    //void readUserInputLoop() {
    public void run() {
	//loop reading from commandline, break() upon reading keyword QUIT!
	String nextLine;
	while(true) {
	    try {
		nextLine = readFromCommandline.readLine();
		if(!(nextLine.equalsIgnoreCase(quitKeyword)))
		    chat.sendMsgFromUser(nextLine, userName);		
		else {
		    //user wants to leave chat
		    chat.unregister(userName);
		    break;
		}

		Thread.sleep(200); //making sure client threads take turns

	    } catch (IOException e) {
		// TODO Auto-generated catch block
		e.printStackTrace();
	    } catch (InterruptedException e) {
		System.err.println("User input loop interrupted " + 
			"while sleeping: " + e);
		e.printStackTrace();
	    }
	}
    }

    /**
     * Starts chat client and initiates access to chat server.
     * 
     * @param args rmi-host-and-service-id username
     */
    public static void main(String[] args) {
	if (args.length != 2 || !args[0].startsWith("rmi://")) {
	    System.err.println("usage: java ChatClient rmi://host.domain:port/chat <username>\n" +
	    "you may omit the port parameter, in which case it defaults to 1099");
	    return;
	}

	try {
	    Object lookupObj = Naming.lookup(args[0]);
	    final Chat chatServer = (Chat) lookupObj;

	    final String userName = args[1];
	    //init chatClient with username and server to talk to
	    //ChatClient chatClient = new ChatClient(userName, chatServer);
	    new Thread(new ChatClient(userName, chatServer)).start();


	    //start another thread polling messages from server
	    new Thread(new Runnable() {

		public void run() {
		    while(true){
			try {
			    String currentMsg = chatServer.getMsgForUser(userName);
			    if(currentMsg != null){
				System.out.println(currentMsg);
			    } else {
				Thread.sleep(400); //making sure client threads take turns
			    }
			} catch (RemoteException e) {
			    System.err.println("Could not get message " +
				    "for user " + userName);
			} catch (InterruptedException e) {
			    System.err.println("Message polling thread was" + 
				    "interrupted while sleeping: " + e);
			} 
		    }
		}

	    }).start();


	} catch (MalformedURLException e) {
	    System.err.println(args[0] + " is not a valid RMI URL, see exception " + e);
	} catch (RemoteException e) {
	    System.err.println("Remote object threw exception " + e);
	    e.printStackTrace();
	} catch (NotBoundException e) {
	    System.err.println("Could not find the requested object on the server: " + e);
	}

    }

}
